<?php
/**
 * 开发模式保留
 * 发布模式删除
 */
defined('IN_IA') or exit('Access Denied');

/**
 * 简单实现的文件缓存，仅做开发者开发测试使用, 线上线下 Cache 的方法签名完全相同。
 *
 * 支持表结构形如 [key=>?, value=>?, expire=>?]的缓存表
 * @author Gorden
 */
class Cache {
	
	private $dir;
	private $file;
	private $caches;
	
	/**
	 * 文件缓存
	 */
	public function __construct() {
		$this->init();
	}
	
	/**
	 * @param string $key
	 */
	public function get($key) {
		return $this->value($key);
	}
	
	/**
	 * @param array $keys [key1, key2, ...]
	 */
	public function get_many($keys) {
		$keys = array_values($keys);
		$result = array();
		foreach ($keys as $key) {
			$result[$key] = $this->value($key);
		}
		return $result;
	}
	
	/**
	 * @param string $key
	 * @param mixed $value
	 * @param number $expire 秒
	 */
	public function set($key, $value, $expire = 0) {
		if (empty($key) || !isset($value) || $expire < 0) {
			return false;
		}
		$this->caches[$key] = array(
			'key' 		=> $key,
			'value' 	=> $value,
			'expire' 	=> TIMESTAMP + $expire,
		);
		$this->save();
		return true;
	}
	
	/**
	 *
	 * @param string|array $key
	 */
	public function delete($key) {
		$keys = is_array($key) ? array_values($key) : array($key);
		$unset = 0;
		foreach ($keys as $key) {
			if ($this->has_key($key)) {
				$cache = $this->caches[$key];
				unset($this->caches[$key]);
				$unset++;
			}
		}
		if ($unset) {
			$this->save();
		}
	}
	
	public function clean() {
		$this->caches = array();
		$this->save();
	}
	
	private function init() {
		$this->dir = IA_ROOT.'/data/';
		$this->file = IA_ROOT . '/data/cache.txt';
		if (!is_dir($this->dir)) {
			$this->mkdirs($this->dir);
		}
		if (!file_exists($this->file)) {
			$fp = fopen($this->file, 'wb');
			fclose($fp);
			if (!file_exists($this->file)) {
				die('加载缓存失败。');
			}
		}
		$this->load();
	}
	
	private function load() {
		$content = file_get_contents($this->file);
		if (empty($content) || !is_serialized($content)) {
			$this->caches = array();
		} else {
			$this->caches = iunserializer($content);
		}
		if ($this->caches) {
			$unset = 0;
			foreach ($this->caches as $key => $cache) {
				if ($this->is_expire($cache)) {
					unset($this->caches[$key]);
					$unset++;
				}
			}
			if ($unset) {
				$this->save();
			}
		}
	}
	
	private function mkdirs($path) {
		if(!is_dir($path)) {
			$this->mkdirs(dirname($path));
			mkdir($path);
		}
		return is_dir($path);
	}
	
	private function save() {
		file_put_contents($this->file, iserializer($this->caches));
	}
	
	private function has_key($key) {
		return array_key_exists($key, $this->caches);
	}
	
	private function value($key) {
		return $this->has_key($key) ? $this->caches[$key]['value'] : null;
	}
	
	private function is_expire($cache) {
		return $cache['expire'] > 0 && $cache['expire'] < TIMESTAMP;
	}
}